package command

import (
	"pan/common/util"

	"github.com/gookit/gcli/v2"
)

type Registry struct {
	app     *gcli.App
	options map[string][]*Option
}

func (r *Registry) Register(name string, commander Commander) {
	cmd := gcli.NewCommand(name, commander.Description(), nil)

	args := commander.Arguments()
	if args != nil {
		for _, desc := range args {
			cmd.AddArg(desc.Name, desc.Description, desc.Required, desc.IsArray)
		}
	}

	options := commander.Options()
	if options != nil {
		r.options[name] = options
		for _, opt := range options {
			switch opt.OptType {
			case IntOption:
				cmd.IntOpt(&opt.IntValue, opt.Name, opt.ShortName, opt.DefaultValue.(int), opt.Description)
			case StrOption:
				cmd.StrOpt(&opt.StrValue, opt.Name, opt.ShortName, opt.DefaultValue.(string), opt.Description)
			case BoolOption:
				cmd.BoolOpt(&opt.BoolValue, opt.Name, opt.ShortName, opt.DefaultValue.(bool), opt.Description)
			}
		}
	}

	cmd.SetFunc(func(c *gcli.Command, args []string) error {
		commander.Run(r.options[name], args)
		return nil
	})
	r.app.Add(cmd)
}

func (r *Registry) Run() {
	r.app.Run()
}

func NewRegistry() *Registry {
	app := gcli.NewApp()
	app.Name = util.CONF_NAME
	app.Version = util.CONF_VERSION
	app.Description = util.CONF_DESCRIPTION
	return &Registry{
		app:     app,
		options: make(map[string][]*Option),
	}
}
